package cn.wolfcode.car.business.service.impl;

import cn.wolfcode.car.business.domain.CarPackageAudit;
import cn.wolfcode.car.business.domain.ServiceItem;
import cn.wolfcode.car.business.mapper.CarPackageAuditMapper;
import cn.wolfcode.car.business.mapper.ServiceItemMapper;
import cn.wolfcode.car.business.query.ServiceItemQuery;
import cn.wolfcode.car.business.service.IBpmnInfoService;
import cn.wolfcode.car.business.service.IServiceItemService;
import cn.wolfcode.car.common.base.page.TablePageInfo;
import cn.wolfcode.car.common.exception.BusinessException;
import cn.wolfcode.car.shiro.ShiroUtils;
import com.github.pagehelper.PageHelper;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.Inflater;

@Service
public class ServiceItemServiceImpl implements IServiceItemService {

    @Autowired
    private ServiceItemMapper serviceItemMapper;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private CarPackageAuditMapper carPackageAuditMapper;
    @Autowired
    private IBpmnInfoService bpmnInfoService;

    @Override
    public TablePageInfo< ServiceItem > query(ServiceItemQuery qo) {
        PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
        return new TablePageInfo<ServiceItem>(serviceItemMapper.selectForList(qo));
    }

    /**
     * 创建的时间是页面没有提交的,这时业务层需要实现
     * 审核状态和上架状态也是没有提交的
     * 审核状态是可以通过是否是套餐来判断是否需要经过审核流程
     * 上架状态默认是未上架的,但是为了防止访问修改需要加一层保护
     * @param serviceItem
     */
    @Override
    public void save(ServiceItem serviceItem) {
        //防止恶意添加数据
        serviceItem.setSaleStatus(ServiceItem.SALESTATUS_OFF);
        serviceItem.setCreateTime(new Date());
        //如果是套餐那么审核状态就是初始化
        if (ServiceItem.CARPACKAGE_YES.equals(serviceItem.getCarPackage())) {
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
        }else {
            //非套餐就是不需要审核
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_NO_REQUIRED);
        }
        serviceItemMapper.insert(serviceItem);
    }

    @Override
    public ServiceItem get(Long id) {
        return serviceItemMapper.selectByPrimaryKey(id);
    }

    /**
     * 1首先需要根据id从数据库中查出数据库中数据
     * 2判断业务是否处于审核中或者是上架状态如果是抛出异常,非法操作
     * 3再判断是否是套餐,是套餐那并且本来状态是审核通过那么要设置成初始化
     * 4把不需要修改的字段在sql中删除掉
     * 不需要修改的,套餐否 日期,上架状态
     * @param serviceItem
     */
    @Override
    public void update(ServiceItem serviceItem) {
        ServiceItem dbServiceItem = serviceItemMapper.selectByPrimaryKey(serviceItem.getId());
        if (ServiceItem.SALESTATUS_ON.equals(dbServiceItem.getSaleStatus())||
                ServiceItem.AUDITSTATUS_AUDITING.equals(dbServiceItem.getAuditStatus())) {
            throw new RuntimeException("非法操作");
        }
        if (ServiceItem.CARPACKAGE_YES.equals(dbServiceItem.getCarPackage())&&
                ServiceItem.AUDITSTATUS_APPROVED.equals(dbServiceItem.getAuditStatus())){
            dbServiceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
        }
        dbServiceItem.setName(serviceItem.getName());
        dbServiceItem.setOriginalPrice(serviceItem.getOriginalPrice());
        dbServiceItem.setDiscountPrice(serviceItem.getDiscountPrice());
        dbServiceItem.setServiceCatalog(serviceItem.getServiceCatalog());
        dbServiceItem.setInfo(serviceItem.getInfo());
        serviceItemMapper.updateByPrimaryKey(dbServiceItem);
    }

    @Override
    public void deleteBatch(Long[] ids) {
        //Long[] dictIds = Convert.toLongArray(ids);
        for (Long dictId : ids) {
            serviceItemMapper.deleteByPrimaryKey(dictId);
        }
    }

    @Override
    public List<ServiceItem> list() {
        return serviceItemMapper.selectAll();
    }

    @Override
    public void saleOn(Long id) {

        //如果是套餐而必须是审核通过的才能进行上架,剩下的也就是没什么限制
        ServiceItem serviceItem = serviceItemMapper.selectByPrimaryKey(id);
        if (ServiceItem.CARPACKAGE_YES.equals(serviceItem.getCarPackage())
        && !ServiceItem.AUDITSTATUS_APPROVED.equals(serviceItem.getAuditStatus())
        ) {
            throw new RuntimeException("非法操作");
        }

        serviceItemMapper.updateSaleStatus(id,ServiceItem.SALESTATUS_ON);
    }

    @Override
    public void saleOff(Long id) {
        serviceItemMapper.updateSaleStatus(id,ServiceItem.SALESTATUS_OFF);
    }

    @Override
    @Transactional
    public void startAudit(Long id, Long bpmnInfoId, Long director, Long finance, String info) {
        ServiceItem serviceItem = serviceItemMapper.selectByPrimaryKey(id);
        //1要先判断是否是套餐
        if (!ServiceItem.CARPACKAGE_YES.equals(serviceItem.getCarPackage())) {
            throw  new BusinessException("非法操作");
        }
        //再判断是否是在审核中或者是审核通过
        if (ServiceItem.AUDITSTATUS_AUDITING.equals(serviceItem.getAuditStatus())
                || ServiceItem.AUDITSTATUS_APPROVED.equals(serviceItem.getAuditStatus())) {
            throw  new BusinessException("非法操作");
        }
        //创建对象CarPackageAudit,封装部分存在的信息
        CarPackageAudit carPackageAudit = new CarPackageAudit();
        carPackageAudit.setBpmnInfoId(bpmnInfoId);
        carPackageAudit.setServiceItemId(id);
        carPackageAudit.setCreateTime(new Date());
        carPackageAudit.setInfo(info);
        carPackageAudit.setAuditorId(director);
        carPackageAudit.setCreator(ShiroUtils.getUser().getUserName());
        carPackageAudit.setServiceItemInfo(serviceItem.getInfo());
        carPackageAudit.setServiceItemPrice(serviceItem.getDiscountPrice());
        carPackageAuditMapper.insert(carPackageAudit);
        //设置流程变量
        Map< String, Object > map = new HashMap<>();
        map.put("director",director);
        //输入discountPrice"一定要和bpmn中定义的文件流程变量一致否则报异常,识别不出bpmn文件中流程变量
        //当错误的流程部署后,一定要修改后完成,重新部署流程否则报错,因为再发起审核使用的是之间的流程部署
        map.put("discountPrice",serviceItem.getDiscountPrice().longValue());
        if (finance!=null){
            map.put("finance",finance);
        }
        //开启审核流程
        ProcessInstance processInstance = runtimeService.
                startProcessInstanceByKey(
                        bpmnInfoService.get(bpmnInfoId).getActProcessKey(),
                        carPackageAudit.getId().toString(),
                        map);
        //获得实例对象后将实例对象的id存入到CarPackageAudit对象中
        //修改
        carPackageAuditMapper.updateForInstanceId(carPackageAudit.getId(),processInstance.getId());
        //改变审核状态为审核中
        serviceItemMapper.updateAuditStatus(id,ServiceItem.AUDITSTATUS_AUDITING);
    }
}
